/*
 *                    BioJava development code
 *
 * This code may be freely distributed and modified under the
 * terms of the GNU Lesser General Public Licence.  This should
 * be distributed with the code.  If you do not have a copy,
 * see:
 *
 *      http://www.gnu.org/copyleft/lesser.html
 *
 * Copyright for this code is held jointly by the individual
 * authors.  These should be listed in @author doc comments.
 *
 * For more information on the BioJava project and its aims,
 * or to join the biojava-l mailing list, visit the home page
 * at:
 *
 *      http://www.biojava.org/
 *
 * Created on 15.04.2004
 * @author Andreas Prlic
 *
 */



package dasregistry ;


import java.io.Serializable;
import java.util.*;

import org.biojava.dasobert.das.Capabilities;
import org.biojava.dasobert.das.DasSpec;
import org.biojava.dasobert.dasregistry.*;
import org.biojava.services.das.dao.RegistryUser;

import org.biojava.services.das.registry.DasRegistry;
import org.biojava.services.das.registry.DasRegistrySql;
import org.biojava.services.das.registry.RegistryConfiguration;
import org.biojava.services.das.registry.UserManager;

import org.springframework.beans.factory.BeanFactory;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import dasregistry.validation.Validator;


public class registryBean 

implements Serializable
{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	String REGISTRY ;
	String alertMe;

	int numbcoordinateentries ; 
	String spec;
	public String getSpec() {
		return spec;
	}



	public void setSpec(String spec) {
		this.spec = spec;
	}



	String dasurl      ;
	String nickname;
	String adminemail  ;
	String description;
	String[] cs_types;
	String[] capabilities ;
	String[]  labels;
	String[] testCodes;
	String helperurl;
	String organism;
	String cs_name;
	String owner;
	String validationMessage;
	String bigFileCap;
	
	String ignoreValidation;
	private String[] validCapabilities;
	private int autoId;
	
	public int getAutoId() {
		return autoId;
	}



	public String[] getValidCapabilities() {
		return validCapabilities;
	}



	public void setValidCapabilities(String[] validCapabilities) {
		this.validCapabilities = validCapabilities;
	}



	public registryBean() {
		cs_types         = new String[0];
		capabilities     = new String[0];
		validCapabilities     = new String[0];
		labels           = new String[0];
		testCodes        = new String[0];
		helperurl        = "";
		cs_name          = "";
		nickname         = "";
		ignoreValidation = "";
		owner = "";
		description="";
		spec="";//DasRegistry.SPEC1_5;//set default spec here
		bigFileCap="";
		autoId=-1;//default is unknown
		
		RegistryConfiguration rconfig = new RegistryConfiguration();
		Map configuration = rconfig.getConfiguration();
		REGISTRY = (String) configuration.get("webserviceLocation");

		// the config file switches between the two possible clients ..
		// recommended is DasregistrySql, because it is much quicker ...

		validationMessage = "";
	}

	

	public String getBigFileCap() {
		return bigFileCap;
	}



	public void setBigFileCap(String bigFileCap) {
		this.bigFileCap = bigFileCap;
		String []caps=new String[1];
		caps[0]=bigFileCap;
		this.setCapabilities(caps);
	}



	public void setNumbcoordinateentries(int i) {
		if ( i <1) { i = 1;}

		numbcoordinateentries = i ;
	}

	public int getNumbcoordinateentries() {
		if (numbcoordinateentries==0) {
			numbcoordinateentries=1 ;
		}
		return numbcoordinateentries ;
	}


	public void setCSTypes(String[] s) {
		cs_types = s ;	
	}

	public String[] getCSTypes(){

		return cs_types ;
	}

	
	public void setCapabilities (String[] s) {
		capabilities = s ;	
	}

	public String[] getCapabilities () {
		
		return capabilities ;
	}

	public void setDasurl( String u )
	{
		char lastChar = u.charAt(u.length()-1);
		if ( lastChar  != '/')
			u += "/";

		dasurl = u;
	}

	public void setAdminemail( String value )
	{
		adminemail = value;
	}

	public void setDescription( String value )
	{
		description = value;
	}

	public String getDasurl() { 
		return dasurl; 
	}

	public void setNickname(String name){
		nickname = name;
	}
	public String getNickname(){
		return nickname;
	}

	public String getAdminemail() { return adminemail; }

	public String getDescription() { return description; }

	public boolean hasAlignmentCapability() {
		boolean hasalignmentcap = false ;
		for (int i=0; i<capabilities.length;i++) {
			//System.out.println("capa:"+capabilities[i]);
			if ( capabilities[i].equals("alignment") ) {
				hasalignmentcap = true ;
				break ;
			}
		}
		return hasalignmentcap ;
	}


	////////

	/** return a DasRegistry object. Can be either the AxisClient to
	 * communicate via SOAP (axis) or the SQLRegistry class */
	private DasRegistry getRegistry(){


		BeanFactory ctx=(new ClassPathXmlApplicationContext("SpringDAO.xml"));
			return (DasRegistrySql)ctx.getBean("registryBean");
	}

	

	public void setLabels(String[] l) {
		labels = l ;
	}

	public String[] getLabels() {
		return labels;
	}

	public void setTestCodes(String[] code) {
		testCodes = code;
	}

	public String[] getTestCodes() {
		return testCodes;
	}

	public void setHelperurl(String url) {
		helperurl = url;
	}

	public String getHelperurl() {
		return helperurl;
	}





	/** find DAS services 
	 * @param capability 
	 * @param cs_types 
	 * @param names 
	 * @param organisms 
	 * @param labelst 
	 * @return all das sources that match the arguments*/
	/*public DasSource[] findServices(String capability,  String[] cs_types,String[] names, String[] organisms,String[] labelst){
		//System.out.println("registryBean findServices >" + capability + "< >" + coordinateSystems[0]+"<");
		DasRegistry dri = getRegistry() ;

		return dri.findService(capability,cs_types,names,organisms,labelst);
	}*/

	/** register a new DAS service 
	 * @param ignoreValidation flag if the validation of the das source should be performed. only admins can set this to true!
	 * @return the auto_id of the new das source*/
	public int registerMe( boolean ignoreValidation) {
		DasRegistry dri = getRegistry() ;
		BeanFactory ctx=(new ClassPathXmlApplicationContext("SpringDAO.xml"));
		UserManager manager=(UserManager)ctx.getBean("userManager");
		
		
		if ( ignoreValidation){
			if ( dri instanceof DasRegistrySql ){
				DasRegistrySql dsql = (DasRegistrySql) dri;
				int status = dsql.registerService(dasurl,
						nickname,
						adminemail, 
						description, 
						cs_types, 
						Capabilities.capabilitiesListFromStrings(capabilities), 
						labels, 
						helperurl, 
						testCodes,
						ignoreValidation, DasSpec.convertToRegistrySpecification(spec));
				if ( ! owner.equals("")) {
					DasSource ds = dsql.getDasSourceByURL(dasurl);
					int auto_id = dsql.getAutoID4DasSource(ds);
					RegistryUser user = manager.getUser(owner);
					manager.addOwner(user, auto_id);
				}
				return status;
			}
		}
		
		int status = dri.registerService(dasurl,
				nickname,
				adminemail,
				description,
				cs_types,
				Capabilities.capabilitiesListFromStrings(capabilities),
				labels,
				helperurl,
				testCodes, DasSpec.convertToRegistrySpecification(spec), ""
		);
System.out.println("status="+status);
		if(status!=1 & status<13)return status;//don't go on to get the auto_id as the server failed and so will not have one!!
		//TODO: expose the setOwner through SOAP... 
		 // (and add a security layer over this
		// in the .JSP this is done via the OpenID authentication
		if ( ! owner.equals("")) {
			System.out.println("owner in registrBean="+owner);
			System.out.println("url="+dasurl);
			if ( dri instanceof DasRegistrySql ){ 
				DasRegistrySql dsql = (DasRegistrySql) dri;
				
				DasSource ds = dsql.getDasSourceByURL(dasurl);
				int auto_id = dsql.getAutoID4DasSource(ds);
				if(auto_id!=-1){//if auto_id is known then allocate this source to the user
					
				
				RegistryUser user = manager.getUser(owner);
				manager.addOwner(user, auto_id);
				this.setAutoId(auto_id);
				return 1;//owner owns source so just say ok then they don't need a passkey
				}
				
			}
		}
		
		return status;
		
	}

	
	

	private void setAutoId(int auto_id) {
		this.autoId=auto_id;
		
	}



	public String getIgnoreValidation() {
		return ignoreValidation;
	}

	public void setIgnoreValidation(String ignoreValidation) {
		this.ignoreValidation = ignoreValidation;
	}

	public void setAlertMe(String alertMe) {
		this.alertMe = alertMe;
	}

	public String getAlertMe() {
		return alertMe;
	}

	/** renew Lease for server
	 * an int is returned, wich provides the status of the request:
	 *  1: successfully renewed
	 *  2:  incorrect key ;
	 *  0: some other error occured;

    DISABLED BY AP

    public int renewLease(String serverurl) {
	DasRegistry dri = getRegistry() ;

	int status = dri.renewLease(serverurl);
	return status ;


    }
	 */
	
	
	
	
	
	/** remove server
	 * an int is returned, wich provides the status of the request:
	 *  1: successfully removed
	 *  2:  incorrect key ;
	 *  0: some other error occured;
	 * @param serverurl 
	 * @param passkey 
	 * @return the status of the request 
	 */
	public int removeService(String serverurl, String passkey) {
		DasRegistry dri = getRegistry() ;

		int status = dri.removeService(serverurl,passkey);
		return status ;
	}

	/** request the key for a server ( to be sent by email to server admin 
	 * @param serverurl 
	 * @param sendmailto 
	 * @return the key */
	public int requestKey(String serverurl, String sendmailto){
		DasRegistry dri = getRegistry() ;
		int status = dri.requestKey(serverurl,sendmailto);
		return status ;
	}




	public String[] getCoordSysTypes() throws Exception {
		DasRegistry dri = getRegistry() ;
		return dri.getCoordSysTypes();


	}


	public String[] getCoordSysByType(String type){
		DasRegistry dri = getRegistry() ;
		return dri.getCoordSysByType(type);
	}

	public void setOrganism(String org) {
		organism = org;
	}
	public String getOrganism() {
		return organism;
	}

	public void setCSName(String csname){
		cs_name = csname;
	}
	public String getCSName() {
		return cs_name;
	}


	public DasSource getDasSourceByURL(String dassourceurl){
		BeanFactory ctx=(new ClassPathXmlApplicationContext("SpringDAO.xml"));
		DasRegistrySql registry=(DasRegistrySql)ctx.getBean("registryBean");
	    return registry.getDasSourceByURL(dassourceurl);
	}
	
	public DasSource getDasSource(String auto_id){
		DasRegistry dri = getRegistry() ;
		return dri.getDasSource(auto_id);
	}

	/** try to validate a server, returns valid capabilities with error messages and lights for validateServer.jsp
	 * @param url 
	 * @param testcode 
	 * @param capabilities 
	 * @param ontology 
	 * @return capabilities that are o.k.*/
	public ValidationResultLights validate(String url, 
			String testcode,
			String[] capabilities,
			String ontology, String auto_id){
		System.out.println("running validate in registryBean");
		
		
		boolean nullCheck = false;
		validationMessage = "";
		if ( capabilities == null) {
			validationMessage = " no capabilities stated.";
			nullCheck = true;
		}
		
		if ( url == null || url.equals("")){
			validationMessage += " no url stated for server.";
			nullCheck = true;
		}
		
		if ( testcode == null || testcode.equals("")){
			validationMessage += " no testcode stated.";
			nullCheck = true;
		}
				
		if ( nullCheck){
			
		ValidationResultLights dummy=	new ValidationResultLights();
			dummy.setErrors(validationMessage);
			return dummy;
		}
			
		
		DasRegistry dri = getRegistry() ;
		boolean ontologyBool=false;
		if (ontology == null){
			ontologyBool=false;
		//System.out.println("ontology selected: " + ontology);
		}else
		if (ontology.equals("on")){
			ontologyBool=true;
		}
		Validator validator=new Validator();
		boolean updateDatabase=true;
		DasCoordinateSystem coord=new DasCoordinateSystem();
		coord.setTestCode(testcode);
		DasCoordinateSystem[]coords={coord};
		DasSpec dasSpec=DasSpec.convertToRegistrySpecification(spec);
		System.out.println("running validate in registryBean with spec="+dasSpec.toString());
	List list=Capabilities.capabilitiesListFromStrings(capabilities);
		return validator.getLights(dasSpec, url,list,coords,ontologyBool,updateDatabase, dri, auto_id, "queryUri here");
		
	
	}

	public String getValidationMessage() {
		return validationMessage;
	}


	//TODO: the methods below need to be removed after some more testing !!!

	/**
	 * @return all organisms in registry
	 * 
	 */
	public String[] getOrganisms() {
		//System.err.println("call of deprecated method get Organisms");
		// used by create coordinate system page!
		DasRegistry dri = getRegistry() ;
		return dri.getOrganismsByName();
	}
	
	public String[] getOrganismsByName(String startOfName){
		DasRegistry dri = getRegistry() ;
		return dri.getOrganismsByName(startOfName);
	}


	/**
	 * @return all labels
	 * @deprecated
	 */
	public String[] getAllLabels() {
		System.err.println("call of deprecated method getAllLabels");
		DasRegistry dri = getRegistry();
		return dri.getAllLabels();
	}

	/** contact to DAS registry server and retrieve all possible capabilities 
	 * @return all capabilities
	 * @deprecated
	 */
	public String[] getAllCapabilities() {
		System.err.println("call of deprecated method getAllCapabilities");
		DasRegistry dri = getRegistry() ;
		try {
			return dri.getAllCapabilities();
		} catch (Exception e){
			String[]arr = new String[0];
			return arr;

		}
	}

	/** contact DAS registry and retreive all available coordsys 
	 * @return  all coord sys
	 * 
	
	 * */
	public List<DasCoordinateSystem> getAllCoordinateSystems(){
		// needded for createcoordsys page
		//System.err.println("call of deprecated method getAllCoordinateSystems");
		DasRegistry dri = getRegistry() ;
		List<DasCoordinateSystem> coords = new ArrayList();
		try {
			//System.out.println("registry Bean calling getAllCoordianteSYstem");
			coords = dri.getAllCoordinateSystems();
			//System.out.println("registry Bean calling getAllCoordianteSYstem");
		} catch ( Exception e ){
			e.printStackTrace();
		}

		return coords;
	}

	
	
	
	
	/** find all DAS sources that match to a certain keyword 
	 * @param keyword 
	 * @return das sources that match the keyword 
	 * @deprecated
	 * */
	public List<DasSource> keywordSearch(String keyword) {
		System.err.println("call of deprecated method getAllLabels");
		DasRegistry dri = getRegistry() ;
		try {
			return dri.keywordSearch( keyword);
		}  catch (Exception e){
			e.printStackTrace();
			return null ;
		}
	}



	public String getOwner() {
		return owner;
	}



	public void setOwner(String owner) {
		this.owner = owner;
	}
	

	
	public List<DasCoordinateSystem> getCoordsByName(String startOfName){
		
		// needded for createcoordsys page
		//System.err.println("call of deprecated method getAllCoordinateSystems");
		DasRegistry dri = getRegistry() ;
		List<DasCoordinateSystem> coords = new ArrayList();
		try {
			//System.out.println("registry Bean calling getAllCoordianteSYstem");
			coords = dri.getCoordSysByName(startOfName);
			//System.out.println("registry Bean calling getAllCoordianteSYstem");
		} catch ( Exception e ){
			e.printStackTrace();
		}

		return coords;
	}
	
	
	/**
	 * renew Lease for server an int is returned, wich provides the status of
	 * the request: 1: successfully renewed 0: some other error occured;
	 */
	public int renewLease(String serverUrl){
		DasRegistry dri = getRegistry() ;
		int status=dri.renewLease(serverUrl, true);
		return status;
	}

}



